<template>
  <el-table
      ref="table"
      v-loading="loading"
      :data="data"
      :reserve-selection="reserveSelection"
      :row-key="rowKey"
      border
      element-loading-spinner="el-icon-loading"
      element-loading-text="玩命加载中......"
      highlight-current-row
      show-overflow-tooltip
      stripe
      style="height: calc(100% - 52px)"
      @select="onSelect"
      @select-all="onSelectAll"
      @row-dblclick="onRowDblclick"
      @selection-change="onSelectionChange"
  >

    <el-table-column
        v-if="selection"
        align="center"
        fixed
        header-align="center"
        type="selection"
    />

    <el-table-column
        v-if="index"
        :index="indexMake"
        align="center"
        fixed
        header-align="center"
        label="序号"
        type="index"
    />

    <el-table-column
        v-if="expand"
        align="center"
        header-align="center"
        type="expand"
    >
      <template #default="scope">
        <slot :row="scope.row"/>
      </template>
    </el-table-column>

    <template v-for="field in fields">
      <template v-if="field.type !== 'hidden'">
        <el-table-column
            v-if="field.slot"
            :align="field.align || 'center'"
            :fixed="field.fixed"
            :header-align="field.headerAlign || 'center'"
            :label="field.label"
            :prop="field.prop"
            :width="field.width || ''"
        >
          <template #default="scope">
            <slot :field="field" :name="field.slot" :row="scope.row"/>
          </template>
        </el-table-column>

        <el-table-column
            v-else-if="field.formatter"
            :align="field.align || 'center'"
            :formatter="(row, column) => formatter(field, row, column)"
            :header-align="field.headerAlign || 'center'"
            :label="field.label"
        >
        </el-table-column>

        <el-table-column
            v-else-if="field.type === 'operation'"
            :label="field.label || '操作'"
            :width="field.width"
            align="center"
            fixed="right"
        >
          <template #default="scope">
            <el-button-group>
              <template v-for="button in field.buttons">
                <el-button
                    v-if="button.visible === undefined || button.visible(scope.row)"
                    :icon="button.icon"
                    :link="button.link"
                    :loading="button.loading"
                    :title="button.title"
                    :type="button.type"
                    @click="button.click(scope.row)"
                />
              </template>
            </el-button-group>
          </template>
        </el-table-column>

        <el-table-column
            v-else
            :align="field.align || 'center'"
            :fixed="field.fixed"
            :header-align="field.headerAlign || 'center'"
            :label="field.label"
            :prop="field.prop"
            :width="field.width || ''"
        >
        </el-table-column>
      </template>
    </template>
  </el-table>

  <el-pagination v-if="page"
                 :current-page="page.pageNum"
                 :layout="page.layout || layout"
                 :page-size="page.pageSize || pageSize"
                 :page-sizes="page.pageSizes || pageSizes"
                 :total="page.total"
                 @change="page.change"
                 @size-change="page.sizeChange"
                 @current-change="page.currentChange"
  />
</template>

<script setup>
import {getCurrentInstance, reactive, ref} from "vue";

defineOptions({
  name: 'JeesdpTable'
});

const props = defineProps({
  fields: {
    type: Array,
    required: true,
  },
  data: {
    type: Array,
    required: true,
  },
  rowKey: {
    type: String,
    default: 'id'
  },
  height: {
    type: Number
  },
  options: {
    type: Object
  },
  loading: {
    type: Boolean,
    default: false
  },
  index: {
    type: Boolean,
    default: true
  },
  expand: {
    type: Boolean,
    default: false
  },
  selection: {
    type: Boolean,
    default: true
  },
  reserveSelection: {
    type: Boolean,
    default: false
  },
  page: {
    type: Object,
  },
  pageSize: {
    type: Number,
    default: 50
  },
  pageSizes: {
    type: Array,
    default: [10, 20, 30, 40, 50, 100]
  },
  layout: {
    type: String,
    default: 'jumper, prev, pager, next, sizes, total'
  }
});
const {proxy} = getCurrentInstance()

const table = ref();
const emit = defineEmits(['load', 'select', 'selectAll', 'rowDblclick', 'selectionChange',]);

let selectedRows = reactive([]);

const indexMake = (index) => {
  if (props.page) {
    return (props.page.pageNum - 1) * props.page.pageSize + index + 1;
  }
  return index + 1;
}

const onSelect = (selection, row) => {
  emit('select', selection, row)
}

const onSelectAll = (selection) => {
  emit('selectAll', selection)
}

const onRowDblclick = (row, column, event) => {
  emit('rowDblclick', row, column, event)
}

const onSelectionChange = (selection) => {
  selectedRows = selection;
}

const getSelectedIds = () => {
  return selectedRows.map((item) => {
    return item[props.rowKey];
  });
}

const getSelectedRows = () => {
  return selectedRows;
}

const formatter = (field, row, column) => {
  return proxy.formatters[field.formatter](field, row, column, props.options);
}

defineExpose({getSelectedIds, getSelectedRows});

</script>

<style scoped>

.el-pagination {
  border: 1px solid #363637;
  border-top: none;
  padding: 10px 20px 10px 0;
  justify-content: end;
}

</style>
